#include <iostream>
#include <thread>
#include <coroutine>
#include <chrono>
#include <memory>
using namespace std;

class IntReader
{
public:
    bool await_ready()
    {
        return false;
    }
    void await_suspend(coroutine_handle<void> handle)
    {
        thread t1([=]()
                  {
            this_thread::sleep_for(chrono::seconds(1));
            handle.resume(); });

        t1.detach();
    }
    int await_resume()
    {
        return 1;
    }
};
class Task
{
public:
    shared_ptr<int> share_int;
    Task(shared_ptr<int> share_int) : share_int{share_int} {}
    int getValue()
    {
        return *share_int;
    }
    class promise_type
    {
    public:
        shared_ptr<int> share_int;
        promise_type() : share_int{make_shared<int>()} {}
        Task get_return_object() { return Task(share_int); }
        suspend_never initial_suspend() { return {}; }
        suspend_never final_suspend() noexcept { return {}; }
        // 1、promise_type 要求 return_void 和 return_value只能二选一实现
        // void return_void(){}
        void return_value(int value)
        {
            *share_int = value;
        }
        void unhandled_exception() { exit(1); }
    };
};
Task prinft_inf()
{
    IntReader r1;
    int res = co_await r1;
    IntReader r2;
    res += co_await r2;
    //  协程函数使用的是co_return,
    // co_return; 不返回 调用：promise_type的return_void函数
    co_return res; // 有具体返回值会调用 ：promise_type的return_value函数
}
int main()
{
    // 1、调用协程函数时会调用返回类型Task内嵌的promise_type类型生成 promise_type实例
    // 2、调用promise_type实例的get_return_object返回协程函数结果 Task 实例
    // 3、当执行到co_return时调用promise_type实例的return_value传递给 Task 实例
    auto t1 = prinft_inf();
    this_thread::sleep_for(chrono::seconds(3));
    cout << "t1's share_int is  " << t1.getValue() << endl;
    cout << "main thread is finish" << endl;
    return 0;
}